package com.aca.market.config;

import com.aca.market.Realm.UserRealm;
import com.aca.market.service.IPermissionService;
import com.aca.market.service.IUserService;
import com.aca.market.service.impl.PermissionServiceImpl;
import com.aca.market.service.impl.UserServiceImpl;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class BeanRegistry implements BeanDefinitionRegistryPostProcessor, ApplicationContextAware {

    private static ApplicationContext context;

    @Bean(name = "shiroFilterFactoryBean")
    public ShiroFilterFactoryBean shiroFilterFactoryBean(){
        //换了自定义
        ShiroFilterFactoryBean bean = new ShiroFilterFactoryBean();
        //设置安全管理器
        log.info("===========setSecurityManager");
        bean.setSecurityManager((org.apache.shiro.mgt.SecurityManager) context.getBean("securityManager"));
//        bean.setSecurityManager(securityManager);
        log.info("===========setSecurityManager OK");

        //添加内置过滤器:
        //anon:无需认证就可以访间
        //authc:必须认证了才能让访问
        //user:必须拥有记住我功能才能用
        //perms:拥有对某 个资源的权限才能访间
        //role:拥有某 个角色权限才能访间

        //无认证就去登陆
        bean.setLoginUrl("/login");
        //未授权情况
        bean.setUnauthorizedUrl("/no-auth");
        return bean;
    }

    @SneakyThrows
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {

        log.info("postProcessBeanDefinitionRegistry");
//        RootBeanDefinition userRealm = new RootBeanDefinition(UserRealm.class);
//        beanDefinitionRegistry.registerBeanDefinition("userRealm",userRealm);

        RootBeanDefinition securityManager = new RootBeanDefinition(DefaultWebSecurityManager.class);
        beanDefinitionRegistry.registerBeanDefinition("securityManager",securityManager);
//        DefaultWebSecurityManager tmp = (DefaultWebSecurityManager) context.getBean("securityManager");
        DefaultWebSecurityManager tmp = (DefaultWebSecurityManager) context.getBean("securityManager");
        tmp.setRealm((Realm) context.getBean("userRealm"));

//        RootBeanDefinition shiroFilterFactoryBean = new RootBeanDefinition(ShiroFilterFactoryBean.class);
//        System.out.println("setSecurityManager");
//        ReflectionUtils.getInstance().invokeSetterMethod(shiroFilterFactoryBean, "securityManager",
//                (DefaultWebSecurityManager)context.getBean("securityManager"));
//        //要先设为可以访问的
//        System.out.println("setSecurityManager OK");
//        beanDefinitionRegistry.registerBeanDefinition("shiroFilterFactoryBean",shiroFilterFactoryBean);
//        bean.setSecurityManager(securityManager);

        log.info("postProcessBeanDefinitionRegistry Over");
    }
    //----------------------------------------------
    //userRealm需要下面的两个service 先要注入 不然空指针
    @Bean
    public UserRealm userRealm(){
        log.info("=========userRealm");
        return new UserRealm();
    }

    @Bean
    public IUserService userService(){
        log.info("=========userService");
        return new UserServiceImpl();
    }

    @Bean
    public IPermissionService permissionService(){
//        System.out.println("=========permissionService");
        return new PermissionServiceImpl();
    }
    //---------------------------------

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        //过滤策略加入
//        System.out.println("postProcessBeanFactory");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//        System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&& BeanRegistry-ApplicationContext");
        context = applicationContext;
    }
}
